package com.lru;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 实现LRU缓存移除最近最少被访问的节点
 *
 * @author xwj
 * @date 2020/4/22
 */
public class SimpleLruCache<K, V> extends LinkedHashMap<K, V> {
    /**
     * 缓存默认最大数量
     */
    private static final int MAX_SIZE = 100;
    /**
     * 缓存限制
     */
    private int limit;

    public SimpleLruCache() {
        this(MAX_SIZE);
    }

    public SimpleLruCache(int limit) {
        /**
         * 默认情况下，LinkedHashMap 是按插入顺序维护链表。
         * 不过我们可以在初始化 LinkedHashMap，指定 accessOrder 参数为 true，即可让它按访问顺序维护链表
         */
        super(limit, 0.75f, true);
        this.limit = limit;
    }

    public V save(K key, V val) {
        return put(key, val);
    }

    public V getOne(K key) {
        return get(key);
    }

    public boolean exists(K key) {
        return containsKey(key);
    }

    /**
     * 判断节点数是否超限
     *
     * @param eldest
     * @return 超限返回 true，否则返回 false
     */
    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > limit;
    }

    public static void main(String[] args) {
        SimpleLruCache<Integer, Integer> cache = new SimpleLruCache<Integer, Integer>(3);
        cache.put(2, 2);
        cache.put(1, 1);
        cache.put(3, 3);
        // 访问2，2被移动到尾部，此刻1在头部
        cache.get(2);
        // 继续添加，超出限制，移除1
        cache.put(4, 4);
        System.out.println(cache);
    }
}
